const https = require('https');
const iconv = require('iconv-lite');
const Stock = require('../models/stock');

/**
 * 从腾讯股票API获取股票数据
 * @param {string} id - 股票代码，如sz000001
 * @param {object} bar - 传递给回调函数的参数
 * @param {function} cb - 回调函数
 * @returns {Promise<object>} - 股票数据对象
 */
async function get(id, bar, cb) {
    try {
        return new Promise((resolve, reject) => {
            // 打印请求的URL，用于调试
            const url = `https://qt.gtimg.cn/q=${id}`;
            console.log('请求URL:', url);
            
            https.get(url, function(ret) {
                if (ret.statusCode != 200) {
                    const error = new Error(`获取股票数据失败，状态码: ${ret.statusCode}`);
                    if (cb) cb(bar, null, error);
                    return reject(error);
                }
                
                let content = '';
                ret.on('data', function(data) {
                    content += data.toString('utf8');
                });
                
                ret.on('end', async function() {
                    try {
                        console.log('content', content);
                        // 解析股票数据
                        if (!content || !content.includes('=')) {
                            const error = new Error('获取股票数据格式错误');
                            if (cb) cb(bar, null, error);
                            return reject(error);
                        }
                        
                        // 如果返回数据为空或包含""，说明股票代码可能不正确
                        if (content.includes('="";')) {
                            const error = new Error(`股票代码 ${id} 不存在或格式不正确`);
                            if (cb) cb(bar, null, error);
                            return reject(error);
                        }
                        
                        // 腾讯API返回格式：v_sh000001="1~上证指数~000001~3777.99~3766.21~3770.68~363324304~0~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~~20250821104148~11.78~0.31~3784.18~3764.67~3777.99/363324304/529695349930~363324304~52969535~0.76~16.20~~3784.18~3764.67~0.52~566738.68~720079.52~0.00~-1~-1~1.74~0~3775.76~~~~~~52969534.9930~0.0000~0~ ~ZS~12.72~3.04~~~~3784.18~2689.70~3.80~4.78~13.12~4719644368020~~5.01~15.90~4719644368020~~~32.26~-0.06~~CNY~0~~0.00~0";
                        // 股票名称为: 上证指数
                        // 股票代码为: 000001
                        // 股票当前价格为: 3777.99
                        // 股票昨日收盘价为: 3766.21
                        // 股票今日开盘价为: 3770.68
                        // 股票今日最高价为: 3784.18
                        // 股票今日最低价为: 3764.67
                        // 股票今日成交量为: 363324304
                        // 股票今日成交额为: 529695349930
                        //
                        // 基于上述完整数据的字段位置分析（从0开始计数）：
                        // 数据按~分割后的数组索引对应关系：
                        // params[0]  = "1" (未知字段)
                        // params[1]  = "上证指数" (股票名称)
                        // params[2]  = "000001" (股票代码)
                        // params[3]  = "3777.99" (当前价格)
                        // params[4]  = "3766.21" (昨日收盘价)
                        // params[5]  = "3770.68" (今日开盘价)
                        // params[6]  = "363324304" (成交量)
                        // params[33] = "3784.18" (今日最高价) ✓ 确认位置
                        // params[34] = "3764.67" (今日最低价) ✓ 确认位置
                        // params[41] = "3784.18" (重复最高价)
                        // params[42] = "3764.67" (重复最低价)
                        // params[67] = "3784.18" (再次重复最高价)



                        try {
                            const data = content.split('="')[1].split('"')[0];
                            const params = data.split('~');
                            
                            // 检查params是否有效
                            if (!params || params.length < 35) {
                                throw new Error(`股票数据格式不正确，无法解析: ${content}`);
                            }
                            
                            // 处理可能的乱码问题
                            let stockName = params[1];
                            try {
                                // 尝试使用iconv-lite转换编码
                                const buffer = Buffer.from(stockName, 'binary');
                                stockName = iconv.decode(buffer, 'GBK');
                                // 去除可能的非法字符
                                stockName = stockName.replace(/[^\u4e00-\u9fa5a-zA-Z0-9\s]/g, '');
                            } catch (e) {
                                console.warn('处理股票名称编码时出错:', e);
                            }
                            params[1] = stockName;
                            
                            console.log('params', params);
                            
                            // 构建股票对象 - 基于模板数据确认的字段映射
                            const obj = {
                                code: id,
                                name: params[1],                           // 股票名称
                                price: parseFloat(params[3]) || 0,        // 当前价格
                                openPrice: parseFloat(params[5]) || 0,     // 今日开盘价
                                closePrice: null,                          // 当日收盘价（交易时段为null）
                                yesterdayClosePrice: parseFloat(params[4]) || 0, // 昨日收盘价
                                highPrice: parseFloat(params[33]) || 0,    // 今日最高价（确认位置）
                                lowPrice: parseFloat(params[34]) || 0,     // 今日最低价（确认位置）
                                volume: parseFloat(params[6]) || 0,        // 成交量
                                timestamp: new Date()
                            };
                            
                            // 数据验证：确保价格数据的合理性
                            if (obj.highPrice < obj.openPrice || obj.lowPrice > obj.openPrice) {
                                console.warn(`股票 ${id} 价格数据异常，使用开盘价作为最高最低价`);
                                obj.highPrice = Math.max(obj.highPrice, obj.openPrice, obj.price);
                                obj.lowPrice = Math.min(obj.lowPrice, obj.openPrice, obj.price);
                            }
                             console.log('obj', JSON.stringify(obj, null, 2));

                             // 计算涨跌幅（基于昨日收盘价）
                             if (obj.yesterdayClosePrice > 0) {
                                 obj.rate = Math.round((obj.price - obj.yesterdayClosePrice) / obj.yesterdayClosePrice * 10000) / 100;
                             } else {
                                 obj.rate = 0;
                                 console.warn(`股票 ${id} 昨日收盘价为0，无法计算涨跌幅`);
                             }
                             
                             // 判断是否为交易时间结束后（15:00后设置收盘价）
                             const now = new Date();
                             const hour = now.getHours();
                             const minute = now.getMinutes();
                             const currentTime = hour * 60 + minute;
                             const marketCloseTime = 15 * 60; // 15:00
                             
                             if (currentTime >= marketCloseTime) {
                                 obj.closePrice = obj.price; // 设置当日收盘价
                             }
                             
                             // 添加涨跌金额
                             obj.change = Math.round((obj.price - obj.yesterdayClosePrice) * 100) / 100;
                             
                             // 尝试保存到数据库，但不影响数据返回
                             try {
                                 await saveToDatabase(obj);
                             } catch (dbError) {
                                 console.warn(`保存股票 ${id} 数据到数据库时出错，但不影响数据获取:`, dbError.message);
                             }
                             
                             // 调用回调函数
                             if (cb) cb(bar, obj);
                             resolve(obj);
                        } catch (error) {
                             console.error(`解析股票 ${id} 数据失败:`, error);
                             if (cb) cb(bar, null, error);
                             reject(error);
                        }
                    } catch (error) {
                        console.error(`处理股票 ${id} 数据失败:`, error);
                        if (cb) cb(bar, null, error);
                        reject(error);
                    }
                });
                
                ret.on('error', function(error) {
                    console.error(`获取股票 ${id} 数据网络错误:`, error);
                    if (cb) cb(bar, null, error);
                    reject(error);
                });
            });
        });
    } catch (error) {
        console.error(`获取股票 ${id} 数据失败:`, error);
        if (cb) cb(bar, null, error);
        throw error;
    }
}

/**
 * 将股票数据保存到数据库
 * @param {object} stockData - 股票数据对象
 * @returns {Promise<boolean>} - 是否成功保存
 */
async function saveToDatabase(stockData) {
    try {
        // 确保股票存在于数据库中，并提供默认名称防止undefined
        const stockName = stockData.name || `股票${stockData.code}`;
        const stockId = await Stock.addStock(stockData.code, stockName);
        
        // 添加价格记录
        await Stock.addStockPrice(
            stockId,
            stockData.price,
            stockData.openPrice,
            stockData.closePrice, // 如果是交易时间结束后，会有收盘价
            stockData.highPrice,
            stockData.lowPrice,
            stockData.yesterdayClosePrice, // 昨日收盘价
            stockData.volume, // 成交量
            stockData.timestamp
        );
        
        console.log(`股票 ${stockData.code} (${stockData.name}) 数据已保存到数据库，当前价格: ${stockData.price}，涨跌幅: ${stockData.rate}%`);
        return true;
    } catch (error) {
        // 只记录错误，不抛出异常，避免中断程序执行
        console.warn(`保存股票 ${stockData.code} 数据到数据库失败 (可能是数据库未连接): ${error.message}`);
        return false;
    }
}

/**
 * 批量获取多个股票数据
 * @param {string[]} stockCodes - 股票代码数组
 * @returns {Promise<object[]>} - 股票数据数组
 */
async function batchGet(stockCodes) {
    try {
        console.log(`开始批量获取 ${stockCodes.length} 只股票数据...`);
        
        // 使用Promise.allSettled而不是Promise.all，确保部分失败不会影响整体
        const results = await Promise.allSettled(stockCodes.map(code => get(code, null, null)));
        
        // 过滤出成功的结果
        const successfulResults = results
            .filter(result => result.status === 'fulfilled')
            .map(result => result.value);
        
        // 记录失败的股票代码
        const failedCodes = [];
        results.forEach((result, index) => {
            if (result.status === 'rejected') {
                failedCodes.push(stockCodes[index]);
                console.error(`股票 ${stockCodes[index]} 获取失败: ${result.reason.message}`);
            }
        });
        
        if (failedCodes.length > 0) {
            console.warn(`以下股票数据获取失败: ${failedCodes.join(', ')}`);
        }
        
        console.log(`成功获取 ${successfulResults.length} 只股票数据`);
        return successfulResults;
    } catch (error) {
        console.error('批量获取股票数据失败:', error);
        throw error;
    }
}

module.exports = {
    get,
    batchGet,
    saveToDatabase
}